package com.winit.project.core.code;

import com.winit.common.util.ShellRunUtil;
import com.winit.core.ci.vcs.VCS;
import com.winit.core.ci.vcs.exception.VCSException;
import com.winit.core.ci.vcs.handler.SvnVersionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.File;

/**
 * 抽象一个可以构建发布包的代码(路径),比如一个maven工程的代码或者php的代码.
 *
 *
 * Created by wangjian on 16/8/1.
 */
public class ProjectCode {

    private static final Logger logger = LoggerFactory.getLogger(ProjectCode.class);

    /**
     *
     */
    //本地工程代码绝对路径
    protected String codePath;
    /**
     *
     */
    private VCS vcs;

    protected String projectName;

    private SvnVersionHandler handler = null;

    /**
     * 构造一个基本的代码对象,需使用工程名称(与project路径一致),代码存放路径,版本控制器对象.
     *
     * @param projectName
     * @param codePath
     * @param vcs
     */
    public ProjectCode(String projectName,String codePath,VCS vcs){
        this.projectName = projectName;
        this.codePath = codePath;
        this.vcs = vcs;
    }

    public String getCodePath(){
        return this.codePath;
    }

    public boolean updateProjectCode() throws VCSException{
        return this.vcs.doUpdate();
    }

    /**
     *
     * 执行下载代码.
     * 下载代码之前,先删除旧代码.
     * 主要用于旧代码不可更新的场合(比如vcs地址变更)
     *
     * @return
     * @throws VCSException
     */
    public boolean removeOldAndCheckNew() throws VCSException{
        //先删除旧代码文件
        this.removeOldCode();
        //检出新代码
        return this.checkOutProjectCode();
    }

    /**
     * 删除工程旧代码
     * 保存工程信息时调用 避免出现修改svn地址后仍使用旧地址代码的情况
     * @return
     * @throws VCSException
     */
    public boolean removeOldCode() throws VCSException {
        if(StringUtils.isEmpty(this.codePath)){
            logger.error("删除工程旧代码,路径为空");
            throw new VCSException("删除工程旧代码,路径为空");
        }

        String str = ShellRunUtil.runCmds("rm","-rf",this.codePath);
        if(!StringUtils.isEmpty(str)){
            logger.error("删除工程旧代码异常,codePath="+this.codePath+",desc="+str);
            throw new VCSException("删除工程旧代码异常,codePath="+this.codePath+",desc="+str);
        }
        return true;
    }

    /**
     * 执行下载/更新代码.
     *
     * 根据代码路径存在与否,决定下载还是更新代码.
     *
     * @return
     * @throws VCSException
     */
    public boolean checkOutProjectCode() throws VCSException{
        File file = new File(this.codePath);
        this.vcs.setHandler(this.handler);
        if(file.exists()){
            return this.vcs.doUpdate();
        }else {
            return this.vcs.doCheckOut();
        }
    }

    public void setHandler(SvnVersionHandler handler) {
        this.handler = handler;
    }
}
